package com.knife.lov.domain.service.impl;

import com.knife.lov.domain.entity.KnifeCode;
import com.knife.lov.domain.entity.KnifeCodeValue;
import com.knife.lov.domain.service.KnifeAbstractLovCacheAble;
import com.knife.lov.infra.cache.v2.KnifeCodeCache;
import com.knife.lov.infra.cache.v2.KnifeCodeValueCache;
import com.knife.lov.infra.constants.CodeValueSupportType;
import com.knife.oauth.tenant.aspect.KnifeTenantAdvice;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @author tianhao.luo@hand-china.com
 * @date 2021年11月15日 10:54 上午
 * 2022-02-24 将LovCacheAble
 */
@Component
public class KnifeRedisCacheAble extends KnifeAbstractLovCacheAble {

    /**
     * 局部缓存，避免同一个lovCode多次进行取值
     *
     * @author tianhao.luo@hand-china.com
     * @date 2021/11/17 3:30 下午
     */
    public static ThreadLocal<Map<String, Map<CodeValueSupportType, Map<String, String>>>> localCache = ThreadLocal.withInitial(HashMap::new);
    @Resource
    private KnifeCodeCache knifeCodeCache;
    @Resource
    private KnifeCodeValueCache knifeCodeValueCache;

    @Override
    protected String selectMeaning(String lovCode, String source, CodeValueSupportType codeValueSupportType) {
        Map<String, Map<CodeValueSupportType, Map<String, String>>> cacheMap = localCache.get();
        Map<CodeValueSupportType, Map<String, String>> codeValueSupportTypeMap = cacheMap.getOrDefault(lovCode, new HashMap<>(6));
        cacheMap.putIfAbsent(lovCode, codeValueSupportTypeMap);
        Map<String, String> lovValueMap = codeValueSupportTypeMap.getOrDefault(codeValueSupportType, new HashMap<>(6));
        codeValueSupportTypeMap.putIfAbsent(codeValueSupportType, lovValueMap);
        // 构造缓存的redisKey时，需要注意添加当前的语言；避免PRJ.PHASES_STATUS这种值集无法翻译
        KnifeCode knifeCode = new KnifeCode();
        knifeCode.setCode(lovCode);
        knifeCode.setTenantId(KnifeTenantAdvice.getTenantId());
        Optional.ofNullable(knifeCodeCache.getCache(knifeCode)).ifPresent(code -> {
            KnifeCodeValue knifeCodeValue = new KnifeCodeValue();
            knifeCodeValue.setCodeId(code.getCodeId());
            knifeCodeValue.setValue(source);
            knifeCodeValue.setTenantId(KnifeTenantAdvice.getTenantId());
            KnifeCodeValue value = knifeCodeValueCache.getCache(knifeCodeValue);
            String supportTypeMeaning = codeValueSupportType.type.apply(value);
            lovValueMap.put(value.getValue(), supportTypeMeaning);

        });
        return lovValueMap.get(source);
    }

    /**
     * 清理线程缓存
     *
     * @author tianhao.luo@hand-china.com
     * @date 2021/11/17 3:29 下午
     */
    @Override
    protected void clear() {
        localCache.remove();
    }

}
